using System;
using System.Windows;
using Microsoft.Win32;
using MinoChat.Enums;

namespace MinoChat.Services;

// 使用Windows SystemEvents监控系统主题变化（事件驱动，无需管理员权限且避免轮询开销）
// Auto模式下运行期间用户修改Windows主题设置，应用会立即响应（不需要重启）
// SystemEvents是静态事件，需要在Dispose中手动取消订阅以避免内存泄漏
public class SystemThemeWatcher : IDisposable
{
    private bool _isWatching;
    private ThemeMode _lastKnownTheme;
    // 【重点】系统主题变化事件，ThemeService订阅后负责当用户修改Windows设置的时候更换主题
    // 主题变化后在UI线程上触发该事件
    public event EventHandler<ThemeMode>? SystemThemeChanged;
    // 【1】通过注册表获取当前Windows系统的主题设置Light/Dark
    // 【重点】用户设置为Auto时候，要立即设置当前主题，然后再持续监控主题设置
    public static ThemeMode GetSystemTheme()
    {
        try
        {
            // 通过注册表检查系统是否使用浅色或深色主题
            var key = Registry.CurrentUser.OpenSubKey(
                @"Software\Microsoft\Windows\CurrentVersion\Themes\Personalize");
            if (key != null)
            {
                var appsUseLightTheme = key.GetValue("AppsUseLightTheme");
                if (appsUseLightTheme is int value)
                {
                    return value == 1 ? ThemeMode.Light : ThemeMode.Dark;
                }
            }
        }
        catch
        {
            // 如果无法读取注册表，默认使用浅色主题
            // 暂时不引入Log
        }
        return ThemeMode.Light;
    }
    // 【2】开始监控系统主题变化（使用事件驱动，无轮询开销）
    public void StartWatching()
    {
        if (_isWatching)
            return;
        // 记录当前主题
        _lastKnownTheme = GetSystemTheme();
        // 订阅系统用户偏好设置变化事件
        // 当Windows主题/颜色/外观等系统设置变化时会触发,通用系统级事件且不需要特殊权限
        SystemEvents.UserPreferenceChanged += OnUserPreferenceChanged;
        _isWatching = true;
    }
    // 【3】停止监控(当用户在应用中取消Auto设置时调用)
    public void StopWatching()
    {
        if (!_isWatching)
            return;
        // 取消订阅事件（重要：静态事件必须显式取消订阅以避免内存泄漏）
        SystemEvents.UserPreferenceChanged -= OnUserPreferenceChanged;
        _isWatching = false;
    }
    // 【4】系统用户偏好设置变化时触发
    private void OnUserPreferenceChanged(object sender, UserPreferenceChangedEventArgs e)
    {
        // 只处理一般设置变化（包括主题、颜色等）
        // 过滤掉其他无关的系统设置变化事件，减少不必要的检查
        if (e.Category != UserPreferenceCategory.General)
            return;
        var currentTheme = GetSystemTheme();
        // 如果主题发生变化，触发事件
        if (currentTheme != _lastKnownTheme)
        {
            _lastKnownTheme = currentTheme;
            // 在UI线程上触发事件，确保修改主题的回调在 UI 线程上执行，避免应用闪退
            Application.Current?.Dispatcher.Invoke(() =>
            {
                SystemThemeChanged?.Invoke(this, currentTheme);
            });
        }
    }
    // 释放资源（由 DI 容器在应用关闭时自动调用）
    // SystemEvents 是静态事件，必须显式取消订阅以避免内存泄漏
    public void Dispose()
    {
        StopWatching();
        GC.SuppressFinalize(this);
    }
}
